﻿/**
 * @file CustomProtocolHal.h
 * @brief SSD仿真系统自定义协议处理模块，负责命令收发与缓冲区数据管理。
 */
#ifndef __CustomProtocolHal_h__
#define __CustomProtocolHal_h__

#include "boost/lockfree/spsc_queue.hpp"
#include "SimFrameworkBase/FrameworkThread.h"
#include "BasicTypes.h"
#include "CustomProtocolCommand.h"
#include "HostComm/Ipc/MessageServer.hpp"
#include "Buffer/Hal/BufferHal.h"
#include "Nand/Hal/NandHal.h"

/**
 * @class CustomProtocolHal
 * @brief 自定义协议处理模块，继承自FrameworkThread，负责命令收发与缓冲区数据管理。
 */
class CustomProtocolHal : public FrameworkThread
{
public:
    /**
     * @brief 构造函数，初始化协议处理模块。
     */
    CustomProtocolHal();
    /**
     * @brief 初始化IPC通道和缓冲区管理器。
     * @param protocolIpcName IPC通道名称
     * @param bufferHal 缓冲区管理器指针
     */
    void Init(const char *protocolIpcName = nullptr, BufferHal *bufferHal = nullptr);
    /**
     * @brief 检查是否有待处理命令。
     * @return 是否有命令
     */
    bool HasCommand();
    /**
     * @brief 获取下一个待处理命令。
     * @return 命令指针
     */
    CustomProtocolCommand *GetCommand();
    /**
     * @brief 提交命令响应。
     * @param command 命令指针
     */
    void SubmitResponse(CustomProtocolCommand *command);

public:
    /**
     * @struct TransferCommandDesc
     * @brief 传输命令描述结构体。
     */
    struct TransferCommandDesc;
    /**
     * @class TransferCommandListener
     * @brief 传输命令完成回调接口。
     */
    class TransferCommandListener
    {
    public:
        /**
         * @brief 命令完成回调。
         * @param command 命令描述
         */
        virtual void HandleCommandCompleted(const TransferCommandDesc &command) = 0;
    };

    /**
     * @struct TransferCommandDesc
     * @brief 传输命令描述结构体。
     */
    struct TransferCommandDesc
    {
        /**
         * @enum Direction
         * @brief 数据传输方向。
         */
        enum class Direction
        {
            In, /**< 读入 */
            Out /**< 写出 */
        };

        CustomProtocolCommand *Command;    /**< 命令指针 */
        tSectorOffset CommandOffset;       /**< 命令起始扇区 */
        tSectorCount SectorCount;          /**< 命令扇区数 */
        Direction Direction;               /**< 传输方向 */
        Buffer Buffer;                     /**< 关联缓冲区 */
        tSectorOffset BufferOffset;        /**< 缓冲区偏移 */
        TransferCommandListener *Listener; /**< 命令完成回调 */
    };

public:
    /**
     * @brief 将传输命令加入队列。
     * @param command 传输命令描述
     */
    void QueueCommand(const TransferCommandDesc &command);

protected:
    /**
     * @brief 线程主循环，处理命令。
     */
    virtual void Run() override;

private:
    /**
     * @brief 获取命令对应的缓冲区指针。
     * @param command 命令指针
     * @param offset 扇区偏移
     * @return 缓冲区指针
     */
    U8 *GetBuffer(CustomProtocolCommand *command, const tSectorOffset &offset);
    /**
     * @brief 处理传输命令队列。
     */
    void ProcessTransferCommand();

private:
    std::unique_ptr<MessageServer<CustomProtocolCommand>> _MessageServer;                    ///< IPC消息服务器
    BufferHal *_BufferHal;                                                                   ///< 缓冲区管理器指针
    std::unique_ptr<boost::lockfree::spsc_queue<TransferCommandDesc>> _TransferCommandQueue; ///< 传输命令队列
};

#endif